﻿using System;
using System.Collections.Generic;
using System.Linq;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using YJKGeometryFuncs;

namespace YJKPatternSign.StairsRoomPlanSign.ModelLayer
{
	public class StairPlanDataPacker
	{
		public StairConditionEnum StairConditon
		{
			get
			{
				return this.stairCondition;
			}
			set
			{
				this.stairCondition = value;
			}
		}

		public List<List<FamilyInstance>> LstFamilyInstance
		{
			get
			{
				return this.lstFamilyInstance;
			}
		}

		public Document M_doc
		{
			get
			{
				return this.m_doc;
			}
			set
			{
				this.m_doc = value;
			}
		}

		public List<RevitLinkInstance> LstLinkInstance
		{
			get
			{
				return this.lstLinkInstance;
			}
			set
			{
				this.lstLinkInstance = value;
			}
		}

		public List<KeyValuePair<Wall, int>> LstWalls
		{
			get
			{
				return this.lstWalls;
			}
			set
			{
				this.lstWalls = value;
			}
		}

		public List<KeyValuePair<Grid, int>> LstGrids
		{
			get
			{
				return this.lstGrids;
			}
			set
			{
				this.lstGrids = value;
			}
		}

		public List<KeyValuePair<Stairs, int>> LstStairs
		{
			get
			{
				return this.lstStairs;
			}
			set
			{
				this.lstStairs = value;
			}
		}

		public ViewPlan UseView
		{
			get
			{
				return this.useView;
			}
			set
			{
				this.useView = value;
			}
		}

		public ElementId DetaitlBlockId
		{
			get
			{
				return this.detaitlBlockId;
			}
			set
			{
				this.detaitlBlockId = value;
			}
		}

		public List<XYZ> LstDriections
		{
			get
			{
				return this.lstDriections;
			}
			set
			{
				this.lstDriections = value;
			}
		}

		public List<XYZ> LstStairDriections
		{
			get
			{
				return this.lstStairDriections;
			}
			set
			{
				this.lstStairDriections = value;
			}
		}

		public List<WallElementPacker> LstAllWallElementPacker
		{
			get
			{
				return this.m_lstAllWallElementPacker;
			}
			private set
			{
				this.m_lstAllWallElementPacker = value;
			}
		}

		public ViewData UseViewData
		{
			get
			{
				return this.m_ViewData;
			}
			private set
			{
				this.m_ViewData = value;
			}
		}

		public List<KeyValuePair<FamilyInstance, int>> LstColumns
		{
			get
			{
				return this.m_lstColumns;
			}
			private set
			{
				this.m_lstColumns = value;
			}
		}

		public double NowViewZ
		{
			get
			{
				if (this.UseViewData == null)
				{
					return 0.0;
				}
				if (this.UseViewData.NowViewLevelZ != null)
				{
					return this.UseViewData.NowViewLevelZ.Value;
				}
				return Math.Min(this.UseViewData.BottomHeightZ, this.UseViewData.UnderBottomZ);
			}
		}

		public List<ColumnPacker> LstColumnPackers
		{
			get
			{
				return this.m_lstColumnPackers;
			}
			private set
			{
				this.m_lstColumnPackers = value;
			}
		}

		public List<SameLevelStairsPacker> LstSameLevelStairsPacker
		{
			get
			{
				return this.m_lstSameLevelStairsPacker;
			}
			set
			{
				this.m_lstSameLevelStairsPacker = value;
			}
		}

		public StairPlanDataPacker(Autodesk.Revit.DB.Document m_doc, ElementId detaitlBlockId)
		{
			this.m_doc = m_doc;
			this.detaitlBlockId = detaitlBlockId;
			this.prepareFiled();
		}

		private void prepareFiled()
		{
			this.prepare_UseView();
			this.prepareDriection();
			this.lstLinkInstance = this.prepare_LstElement<RevitLinkInstance>(BuiltInCategory.OST_RvtLinks);
			this.lstWalls = this.prepare_LstElement<Wall>(false, BuiltInCategory.OST_Walls);
			this.PrePareWallElementPacker();
			this.lstGrids = this.prepare_LstElement<Grid>(false, BuiltInCategory.OST_Grids);
			this.LstColumns = this.prepare_LstElement<FamilyInstance>(false, BuiltInCategory.OST_StructuralColumns);
			this.PrePareColumnePacker();
			this.lstStairs = this.prepare_LstStairs();
			this.PrepareSameLevelStairsPacker();
			this.LstSameLevelStairsPacker = this.GetSameLevelStairsGroup(this.LstSameLevelStairsPacker);
			this.LstSameLevelStairsPacker = this.PrepareSameLevelStairsInformation();
		}

		private void prepareDriection()
		{
			this.lstDriections = new List<XYZ>();
			this.LstDriections.Add(this.useView.RightDirection);
			this.LstDriections.Add(this.useView.UpDirection);
		}

		private void prepare_UseView()
		{
			this.useView = null;
			string name = this.m_doc.GetElement(this.detaitlBlockId).Name;
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_doc);
			ElementClassFilter elementClassFilter = new ElementClassFilter(typeof(ViewPlan));
			foreach (Element element in filteredElementCollector.WherePasses(elementClassFilter).ToElements())
			{
				ViewPlan viewPlan = (ViewPlan)element;
				if (viewPlan.Name.Equals(name))
				{
					this.useView = viewPlan;
					this.UseViewData = new ViewData(viewPlan);
				}
			}
			if (this.useView == null)
			{
				throw new ArgumentException();
			}
		}

		private List<KeyValuePair<Stairs, int>> prepare_LstStairs()
		{
			List<KeyValuePair<Stairs, int>> list = new List<KeyValuePair<Stairs, int>>();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_doc);
			ElementClassFilter elementClassFilter = new ElementClassFilter(typeof(Stairs));
			double elevation = this.useView.GenLevel.Elevation;
			int num = 0;
			int num2 = 0;
			bool flag = true;
			double minValue = double.MinValue;
			double minValue2 = double.MinValue;
			Stairs stairs = null;
			Stairs stairs2 = null;
			List<KeyValuePair<Stairs, double>> list2 = new List<KeyValuePair<Stairs, double>>();
			BoundingBoxPakcer boundingBoxPacker = new BoundingBoxPakcer(this.useView.get_BoundingBox(this.useView), elevation, this.lstDriections);
			foreach (Element element in filteredElementCollector.WherePasses(elementClassFilter).ToElements())
			{
				if (element is Stairs)
				{
					flag = true;
					Stairs stairs3 = element as Stairs;
					new List<Line>();
					using (List<Line>.Enumerator enumerator2 = Utility.GetStairBound(stairs3).GetEnumerator())
					{
						while (enumerator2.MoveNext())
						{
							if (!Utility.IfLineInRange(enumerator2.Current, boundingBoxPacker))
							{
								flag = false;
								break;
							}
						}
					}
					if (flag)
					{
						bool flag2;
						StairPlanDataPacker.TryGetElementZ(stairs3, null, out flag2, ref minValue, ref minValue2);
						if (flag2)
						{
							if (!Geometry.Lessthan_Or_Equal(minValue, Math.Min(this.UseViewData.TopHeightZ, this.UseViewData.CutHeightZ)) && Geometry.Lessthan_Or_Equal(minValue2, Math.Min(this.UseViewData.TopHeightZ, this.UseViewData.CutHeightZ)))
							{
								num++;
							}
							else if (!Geometry.LessThan(minValue, this.NowViewZ) && Geometry.Lessthan_Or_Equal(minValue2, this.NowViewZ))
							{
								num2++;
							}
							if (!Geometry.LessThan(Math.Min(this.UseViewData.TopHeightZ, this.UseViewData.CutHeightZ), minValue2) && !Geometry.LessThan(minValue, this.NowViewZ))
							{
								list2.Add(new KeyValuePair<Stairs, double>(stairs3, minValue));
							}
						}
					}
				}
			}
			list2 = (from k in list2
			orderby -k.Value
			select k).ToList<KeyValuePair<Stairs, double>>();
			if (list2.Count > 0)
			{
				stairs = list2[0].Key;
			}
			if (list2.Count > 1)
			{
				stairs2 = list2[1].Key;
			}
			if (num > 0 && num2 > 0)
			{
				this.stairCondition = StairConditionEnum.Normal;
			}
			else if (num == 0 && num2 > 0)
			{
				this.stairCondition = StairConditionEnum.Top;
			}
			else if (num > 0 && num2 == 0)
			{
				this.stairCondition = StairConditionEnum.Down;
			}
			else
			{
				this.stairCondition = StairConditionEnum.Error;
			}
			if (stairs != null)
			{
				list.Add(new KeyValuePair<Stairs, int>(stairs, -1));
			}
			if (stairs2 != null)
			{
				list.Add(new KeyValuePair<Stairs, int>(stairs2, -1));
			}
			return list;
		}

		private List<SameLevelStairsPacker> PrepareSameLevelStairsInformation()
		{
			List<SameLevelStairsPacker> list = new List<SameLevelStairsPacker>();
			double elevation = this.useView.GenLevel.Elevation;
			int num = 0;
			int num2 = 0;
			SameLevelStairsPacker sameLevelStairsPacker = null;
			SameLevelStairsPacker sameLevelStairsPacker2 = null;
			List<SameLevelStairsPacker> list2 = new List<SameLevelStairsPacker>();
			foreach (SameLevelStairsPacker sameLevelStairsPacker3 in this.LstSameLevelStairsPacker)
			{
				double stairsTopValue = sameLevelStairsPacker3.StairsTopValue;
				double stairsBaseValue = sameLevelStairsPacker3.StairsBaseValue;
				if (!Geometry.Lessthan_Or_Equal(stairsTopValue, Math.Min(this.UseViewData.TopHeightZ, this.UseViewData.CutHeightZ)) && Geometry.Lessthan_Or_Equal(stairsBaseValue, Math.Min(this.UseViewData.TopHeightZ, this.UseViewData.CutHeightZ)))
				{
					num++;
				}
				else if (!Geometry.LessThan(stairsTopValue, this.NowViewZ, 0.5 * sameLevelStairsPacker3.GetStepsHeight()) && Geometry.Lessthan_Or_Equal(stairsBaseValue, this.NowViewZ))
				{
					num2++;
				}
				if (!Geometry.LessThan(Math.Min(this.UseViewData.TopHeightZ, this.UseViewData.CutHeightZ), stairsBaseValue) && !Geometry.LessThan(stairsTopValue, this.NowViewZ, 0.5 * sameLevelStairsPacker3.GetStepsHeight()))
				{
					list2.Add(sameLevelStairsPacker3);
				}
			}
			list2 = (from k in list2
			orderby -k.StairsTopValue
			select k).ToList<SameLevelStairsPacker>();
			if (list2.Count > 0)
			{
				sameLevelStairsPacker = list2[0];
			}
			if (list2.Count > 1)
			{
				sameLevelStairsPacker2 = list2[1];
			}
			if (num > 0 && num2 > 0)
			{
				this.stairCondition = StairConditionEnum.Normal;
			}
			else if (num == 0 && num2 > 0)
			{
				this.stairCondition = StairConditionEnum.Top;
			}
			else if (num > 0 && num2 == 0)
			{
				this.stairCondition = StairConditionEnum.Down;
			}
			else
			{
				this.stairCondition = StairConditionEnum.Error;
			}
			if (sameLevelStairsPacker != null)
			{
				list.Add(sameLevelStairsPacker);
			}
			if (sameLevelStairsPacker2 != null)
			{
				list.Add(sameLevelStairsPacker2);
			}
			return list;
		}

		private void PrePareWallElementPacker()
		{
			Dictionary<int, RevitLinkInstance> dictionary = new Dictionary<int, RevitLinkInstance>();
			BoundingBoxPakcer curveMidPoint = new BoundingBoxPakcer(this.useView.get_BoundingBox(this.useView), this.NowViewZ, this.lstDriections);
			dictionary.Add(-1, null);
			this.m_doc.GetElement(this.useView.LevelId);
			double nowViewZ = this.NowViewZ;
			foreach (RevitLinkInstance revitLinkInstance in this.LstLinkInstance)
			{
				if (!dictionary.ContainsKey(revitLinkInstance.Id.IntegerValue))
				{
					dictionary.Add(revitLinkInstance.Id.IntegerValue, revitLinkInstance);
				}
			}
			WallElementPacker wallElementPacker = null;
			for (int i = 0; i < this.lstWalls.Count; i++)
			{
				wallElementPacker = new WallElementPacker(this.lstWalls[i].Key, nowViewZ, dictionary[this.lstWalls[i].Value]);
				wallElementPacker.SetCurveMidPoint(curveMidPoint);
				foreach (FamilyInstance input in this.lstFamilyInstance[i])
				{
					wallElementPacker.AddFamilyInstance(input);
				}
				this.LstAllWallElementPacker.Add(wallElementPacker);
			}
		}

		private void PrePareColumnePacker()
		{
			foreach (KeyValuePair<FamilyInstance, int> keyValuePair in this.m_lstColumns)
			{
				RevitLinkInstance inputRevitLinkInstacne = null;
				if (-1 != keyValuePair.Value)
				{
					inputRevitLinkInstacne = (this.M_doc.GetElement(new ElementId(keyValuePair.Value)) as RevitLinkInstance);
				}
				this.LstColumnPackers.Add(new ColumnPacker(keyValuePair.Key, this, inputRevitLinkInstacne));
			}
		}

		private List<T> prepare_LstElement<T>(BuiltInCategory inputCategory) where T : Element
		{
			BoundingBoxXYZ useBoundingBox = this.useView.get_BoundingBox(this.useView);
			List<T> list = new List<T>();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_doc, this.UseView.Id);
            if ((int)inputCategory == -2000120)
			{
				filteredElementCollector = new FilteredElementCollector(this.m_doc);
			}
			Type typeFromHandle = typeof(T);
			if (typeFromHandle.Name.Equals(typeof(Wall).Name))
			{
				this.lstFamilyInstance = new List<List<FamilyInstance>>();
			}
			ElementClassFilter elementClassFilter = new ElementClassFilter(typeFromHandle);
			FilteredElementCollector filteredElementCollector2 = new FilteredElementCollector(this.m_doc, this.useView.Id);
			ElementFilter elementFilter = new ElementCategoryFilter(BuiltInCategory.OST_Windows);
			ElementCategoryFilter elementCategoryFilter = new ElementCategoryFilter(BuiltInCategory.OST_Doors);
			LogicalOrFilter logicalOrFilter = new LogicalOrFilter(elementFilter, elementCategoryFilter);
			foreach (Element element in filteredElementCollector.WherePasses(elementClassFilter).ToElements())
			{
				int integerValue = element.Id.IntegerValue;
                if ((this.ifBetweenView(element, null) && this.IfInRange(element, useBoundingBox, null, false)) || (int)inputCategory == -2000220 || (int)inputCategory == -2001352)
				{
                    if (element.Category.Id.IntegerValue == (int)inputCategory && element is T)
					{
						list.Add(element as T);
					}
					if (typeFromHandle.Name.Equals(typeof(Wall).Name))
					{
						this.lstFamilyInstance.Add(new List<FamilyInstance>());
						int index = this.lstFamilyInstance.Count - 1;
						foreach (Element element2 in filteredElementCollector2.WherePasses(logicalOrFilter))
						{
							if (this.ifBetweenView(element2, null) && element2 is FamilyInstance && (element2 as FamilyInstance).Host.Id.IntegerValue == element.Id.IntegerValue)
							{
								this.lstFamilyInstance[index].Add(element2 as FamilyInstance);
							}
						}
					}
				}
			}
			return list;
		}

		private List<KeyValuePair<T, int>> prepare_LstElement<T>(bool ifThisDocument, BuiltInCategory inputCategory) where T : Element
		{
			List<KeyValuePair<T, int>> list = new List<KeyValuePair<T, int>>();
			foreach (T key in this.prepare_LstElement<T>(inputCategory))
			{
				list.Add(new KeyValuePair<T, int>(key, -1));
			}
			if (!ifThisDocument)
			{
				ElementClassFilter elementClassFilter = new ElementClassFilter(typeof(T));
				BoundingBoxXYZ useBoundingBox = this.useView.get_BoundingBox(this.useView);
				double elevation = this.useView.GenLevel.Elevation;
				new ElementClassFilter(typeof(Level));
				ElementFilter elementFilter = new ElementCategoryFilter(BuiltInCategory.OST_Windows);
				ElementCategoryFilter elementCategoryFilter = new ElementCategoryFilter(BuiltInCategory.OST_Doors);
				LogicalOrFilter logicalOrFilter = new LogicalOrFilter(elementFilter, elementCategoryFilter);
				foreach (RevitLinkInstance revitLinkInstance in this.lstLinkInstance)
				{
					Document linkDocument = revitLinkInstance.GetLinkDocument();
					foreach (Element element in new FilteredElementCollector(linkDocument).WherePasses(elementClassFilter).WhereElementIsNotElementType())
					{
                        if ((this.ifBetweenView(element, revitLinkInstance.GetTotalTransform()) && this.IfInRange(element, useBoundingBox, revitLinkInstance.GetTotalTransform(), false)) || (int)inputCategory == -2000220)
						{
                            if (element.Category.Id.IntegerValue == (int)inputCategory && element is T)
							{
								list.Add(new KeyValuePair<T, int>(element as T, revitLinkInstance.Id.IntegerValue));
							}
							if (typeof(T).Name.Equals(typeof(Wall).Name))
							{
								FilteredElementCollector filteredElementCollector = new FilteredElementCollector(linkDocument);
								this.lstFamilyInstance.Add(new List<FamilyInstance>());
								int index = this.lstFamilyInstance.Count - 1;
								foreach (Element element2 in filteredElementCollector.WherePasses(logicalOrFilter).WhereElementIsElementType())
								{
									if (element2 is FamilyInstance && (element2 as FamilyInstance).Host.Id.IntegerValue == element.Id.IntegerValue && this.IfInRange(element2, useBoundingBox, revitLinkInstance.GetTotalTransform(), false) && this.ifBetweenView(element2, revitLinkInstance.GetTotalTransform()))
									{
										this.lstFamilyInstance[index].Add(element2 as FamilyInstance);
									}
								}
							}
						}
					}
				}
			}
			return list;
		}

		private bool IfInRange(Element inputElement, BoundingBoxXYZ useBoundingBox, Transform useTransform = null, bool ifChangeBound = false)
		{
			double nowViewZ = this.NowViewZ;
			BoundingBoxPakcer boundingBoxPakcer = new BoundingBoxPakcer(useBoundingBox, nowViewZ, this.lstDriections);
			if (ifChangeBound)
			{
				boundingBoxPakcer.moveBound(Utility.MMToFeet(StaticResource.DistanceOfBoundingBoxToDrawBox, true));
			}
			if (ifChangeBound)
			{
				boundingBoxPakcer.moveBound(Utility.MMToFeet(StaticResource.DistanceOfBoundingBoxToDrawBox, true));
			}
			List<Line> lstBoundLine = boundingBoxPakcer.LstBoundLine;
			if (inputElement.Location is LocationCurve)
			{
				Curve curve = (inputElement.Location as LocationCurve).Curve;
				if (useTransform != null)
				{
					curve = curve.CreateTransformed(useTransform);
				}
				if (Geometry.Lessthan_Or_Equal(curve.Length, 1E-06))
				{
					return true;
				}
				if (curve is Line && ((curve as Line).Direction.IsAlmostEqualTo(XYZ.BasisZ) || (curve as Line).Direction.IsAlmostEqualTo(-XYZ.BasisZ)))
				{
					return Utility.IfPointInRange(new XYZ(curve.GetEndPoint(0).X, curve.GetEndPoint(0).Y, nowViewZ), boundingBoxPakcer);
				}
				return Utility.IfLineInRange(Line.CreateBound(new XYZ(curve.GetEndPoint(0).X, curve.GetEndPoint(0).Y, nowViewZ), new XYZ(curve.GetEndPoint(1).X, curve.GetEndPoint(1).Y, nowViewZ)), boundingBoxPakcer);
			}
			else
			{
				if (inputElement.Location is LocationPoint)
				{
					XYZ xyz = (inputElement.Location as LocationPoint).Point;
					if (useTransform != null)
					{
						xyz = Geometry.TransformPoint(xyz, useTransform);
					}
					return Utility.IfPointInRange(xyz, boundingBoxPakcer);
				}
				if (inputElement is Grid)
				{
					Line line = (inputElement as Grid).Curve as Line;
					if (null == line)
					{
						return false;
					}
					if (useTransform != null)
					{
						line = (line.CreateTransformed(useTransform) as Line);
					}
					line = (Utility.ChangeCurveZ(line, nowViewZ) as Line);
					return Utility.IfLineInRange(line, boundingBoxPakcer);
				}
				else
				{
					if (inputElement is Stairs)
					{
						foreach (Curve curve2 in Utility.ChangeLstCurveZ(Utility.GetListTransformCurve(Utility.GetStairBound(inputElement as Stairs).Cast<Curve>().ToList<Curve>(), useTransform), nowViewZ))
						{
							if (!(null == curve2) && curve2 is Line && !Utility.IfLineInRange(curve2 as Line, boundingBoxPakcer))
							{
								return false;
							}
						}
						return true;
					}
					return false;
				}
			}
		}

		private bool ifBetweenView(Element input, Transform useTransform = null)
		{
			double elevation = this.useView.GenLevel.Elevation;
			double num = 0.0;
			double val = 0.0;
			bool flag = false;
			StairPlanDataPacker.TryGetElementZ(input, useTransform, out flag, ref num, ref val);
			if (!flag)
			{
				return false;
			}
			if (input is Stairs)
			{
				return !Geometry.Lessthan_Or_Equal(Math.Min(this.UseViewData.TopHeightZ, this.UseViewData.CutHeightZ) - 1E-06, val);
			}
			return !Geometry.Lessthan_Or_Equal(num, Math.Min(elevation, this.NowViewZ) - 1E-06) && !Geometry.Lessthan_Or_Equal(Math.Max(this.UseViewData.TopHeightZ, elevation) + 1E-06, val) && !Geometry.LessThan(num - Math.Min(elevation, this.NowViewZ), AssistFunc.mmToFeet(10.0));
		}

		private static void TryGetElementZ(Element input, Transform useTransform, out bool ifSucess, ref double elementTopZ, ref double elementDownZ)
		{
			ifSucess = true;
			BoundingBoxXYZ boundingBoxXYZ = input.get_BoundingBox(null);
			if (boundingBoxXYZ == null)
			{
				ifSucess = false;
				return;
			}
			if (useTransform != null)
			{
				XYZ xyz = boundingBoxXYZ.Max;
				XYZ xyz2 = boundingBoxXYZ.Min;
				xyz = Geometry.TransformPoint(xyz, useTransform);
				xyz2 = Geometry.TransformPoint(xyz2, useTransform);
				boundingBoxXYZ = new BoundingBoxXYZ();
				boundingBoxXYZ.Max = xyz;
				boundingBoxXYZ.Min = xyz2;
			}
			elementTopZ = boundingBoxXYZ.Max.Z;
			elementDownZ = boundingBoxXYZ.Min.Z;
		}

		private bool ifInRange(Element inputElement, BoundingBoxXYZ useBoundingBox, Level useLevel, bool ifChangeBound = false)
		{
			double elevation = useLevel.Elevation;
			BoundingBoxPakcer boundingBoxPakcer = new BoundingBoxPakcer(useBoundingBox, elevation, this.lstDriections);
			if (ifChangeBound)
			{
				boundingBoxPakcer.moveBound(Utility.MMToFeet(StaticResource.DistanceOfBoundingBoxToDrawBox, true));
			}
			List<Line> lstBoundLine = boundingBoxPakcer.LstBoundLine;
			if (inputElement.Location is LocationCurve)
			{
				Curve curve = (inputElement.Location as LocationCurve).Curve;
				return Utility.IfLineInRange(Line.CreateBound(new XYZ(curve.GetEndPoint(0).X, curve.GetEndPoint(0).Y, elevation), new XYZ(curve.GetEndPoint(1).X, curve.GetEndPoint(1).Y, elevation)), boundingBoxPakcer);
			}
			return inputElement.Location is LocationPoint && Utility.IfPointInRange((inputElement.Location as LocationPoint).Point, boundingBoxPakcer);
		}

		private void PrepareSameLevelStairsPacker()
		{
			List<KeyValuePair<Stairs, int>> list = this.prepare_LstElement<Stairs>(false, BuiltInCategory.OST_Stairs);
			List<SameLevelStairsPacker> list2 = new List<SameLevelStairsPacker>();
			foreach (KeyValuePair<Stairs, int> keyValuePair in list)
			{
				RevitLinkInstance inputLinkInstance = null;
				if (keyValuePair.Value != -1)
				{
					inputLinkInstance = (this.M_doc.GetElement(new ElementId(keyValuePair.Value)) as RevitLinkInstance);
				}
				list2.Add(new SameLevelStairsPacker(keyValuePair.Key, inputLinkInstance));
			}
			this.LstSameLevelStairsPacker.AddRange(list2);
		}

		private List<SameLevelStairsPacker> GetSameLevelStairsGroup(List<SameLevelStairsPacker> input)
		{
			List<SameLevelStairsPacker> list = new List<SameLevelStairsPacker>();
			List<List<SameLevelStairsPacker>> list2 = new List<List<SameLevelStairsPacker>>();
			List<SameLevelStairsPacker> list3 = new List<SameLevelStairsPacker>();
			input = (from k in input
			orderby -k.StairsTopValue
			select k).ToList<SameLevelStairsPacker>();
			for (int i = 0; i < input.Count; i++)
			{
				list3.Add(input[i]);
				if (i != input.Count - 1)
				{
					if (!Geometry.Lessthan_Or_Equal(input[i + 1].StairsTopValue, input[i].StairsTopValue) || !Geometry.Lessthan_Or_Equal(input[i].StairsBaseValue, input[i + 1].StairsBaseValue))
					{
						list2.Add(list3);
						list3 = new List<SameLevelStairsPacker>();
					}
				}
				else
				{
					list2.Add(list3);
					list3 = new List<SameLevelStairsPacker>();
				}
			}
			foreach (List<SameLevelStairsPacker> list4 in list2)
			{
				if (list4.Count != 0)
				{
					list.Add(list4[0]);
					for (int j = 1; j < list4.Count; j++)
					{
						list4[0].ApeendPacker(list4[j]);
					}
				}
			}
			return list;
		}

		private Document m_doc;

		private List<WallElementPacker> m_lstAllWallElementPacker = new List<WallElementPacker>();

		private List<RevitLinkInstance> lstLinkInstance;

		private List<KeyValuePair<Wall, int>> lstWalls;

		private List<List<FamilyInstance>> lstFamilyInstance;

		private List<KeyValuePair<Grid, int>> lstGrids;

		private List<KeyValuePair<Stairs, int>> lstStairs;

		private List<KeyValuePair<FamilyInstance, int>> m_lstColumns;

		private ViewPlan useView;

		private ViewData m_ViewData;

		private ElementId detaitlBlockId;

		private List<XYZ> lstDriections;

		private List<XYZ> lstStairDriections;

		private StairConditionEnum stairCondition;

		private List<ColumnPacker> m_lstColumnPackers = new List<ColumnPacker>();

		private List<SameLevelStairsPacker> m_lstSameLevelStairsPacker = new List<SameLevelStairsPacker>();
	}
}
